Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SD utility pool #212

Merged
merged 122 commits into from
Apr 1, 2024
Merged

SD utility pool #212

merged 122 commits into from
Apr 1, 2024

Conversation

sanjay-staderlabs
Copy link
Contributor

@sanjay-staderlabs sanjay-staderlabs commented Nov 14, 2023

This PR introduces SD Utility Pool. where NO can utilise SD for collateral, following are the major changes

  • New SD Utility Pool Contract which deals with delegators and utilizers
  • New SDIncentiveController contract, which handles the distribution of reward tokens for the utility pool.
  • New Call in Permissionless Node Registry to add validator along with utilizing SD
  • New Deposit and Repay function in SDCollateral contract to interact with Utility Pool
  • introduction of getter and setter for utility pool contract and incentive controller in Stader Config
  • Feature to allow NOs to deposit their SD rewards as collateral

@sanjay-staderlabs sanjay-staderlabs marked this pull request as ready for review November 17, 2023 15:08
Sanjay Yadav and others added 4 commits November 20, 2023 16:54
@@ -46,6 +49,30 @@ contract OperatorRewardsCollector is IOperatorRewardsCollector, AccessControlUpg
emit Claimed(operatorRewardsAddr, amount);
}

function claimFor(address operator) external {
uint256 toSendAmount;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need this variable? No usages right?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add documentation? This logic is not very clear.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add documentation? This logic is not very clear.


if (opSDBalance < getOperatorWithdrawThreshold(operator) + _requestedSD) {
revert InsufficientSDToWithdraw(opSDBalance);
}
operatorSDBalance[operator] -= _requestedSD;
uint256 operatorCurrentUtilizeSD = ISDUtilityPool(staderConfig.getSDUtilityPool()).utilizerBalanceCurrent(
Copy link

@galacticminter galacticminter Nov 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fn can called .currentBalance()

// cannot use safeERC20 as this contract is an upgradeable contract, and using safeERC20 is not upgrade-safe
if (!IERC20(staderConfig.getStaderToken()).transfer(payable(operator), _requestedSD)) {
revert SDTransferFailed();
uint256 utilizePositionChange = operatorUtilizedSD >= _requestedSD ? _requestedSD : operatorUtilizedSD;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No easier way to do Math.min()?

if (!IERC20(staderConfig.getStaderToken()).transfer(payable(operator), _requestedSD)) {
revert SDTransferFailed();
uint256 utilizePositionChange = operatorUtilizedSD >= _requestedSD ? _requestedSD : operatorUtilizedSD;
operatorUtilizedSDBalance[operator] -= utilizePositionChange;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SDRequestedLeft = SDRequested;
interestAccrued = operatorTotalUtilizedSD - operatorRecordedUtilizedSD // difference between the two is interest

interestPaid = Math.min(SDRequestedLeft, interestAccrued);
sdRequestedLeft -= interestPaid;
//Update repay amount in SDUtilityPool by transferring interestPaid tokens. Might have to update both utilized and bonded positions.

if (sdRequestedLeft == 0) { // You are done.}

utilizedPositionRepayAmount = Math.min(sdRequestedLeft, operatorRecordedUtilizedSD)
sdRequestedLeft -= utilizedPositionRepayAmount;
//definitely decrease the RecordedUtilizedSD & increment the Self Bonded SD & transfer utilizedPositionRepayAmount tokens to SD utilization pool.


if (sdRequestedLeft == 0) { // You are done}

// At this stage all interest + utilized amount has been repaid. The rest can to operator wallet & only self bonded position will be decremented

Will optimize this further.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SDRequestedLeft = SDRequested;
operatorTotalUtilizedSD = utilityPool.currentUtilizedAmount(operator);

repayAmount = Math.min(SDRequestedLeft, operatorTotalUtilizedSD);
sdRequestedLeft -= repayAmount;
// transfer repayAmount tokens to SD utility pool. Decrement total utilized balance on pool & operator current utilized balance on pool.
interestPaid = Math.min(repayAmount, operatorTotalUtilizedSD - operatorRecordedUtilizedSD); // How do we make sure this math works for incentivized lending when the 2nd term might be negative?
utilizedAmountPaid = repayAmount - interestPaid;
operatorRecordedUtilizedSD -= utilizedAmountPaid;
SDBalances[operator] += utilizedAmountPaid;

if (sdRequestedLeft > 0) {
// Send sdRequestedLeft tokens to operator wallet.
}

return (interestPaid, utilizedAmountPaid, sdRequestedLeft);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the above simpler?

Copy link
Contributor Author

@sanjay-staderlabs sanjay-staderlabs Nov 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will push another implementation of this, mostly the same as above, with a change that the repay function will return the actual repayment amount.

emit SDSlashed(_operator, staderConfig.getAuctionContract(), sdSlashed);
}

/// @notice for max approval to auction contract for spending SD tokens
/// @notice for max approval to auction/SD utility pool contract for spending SD tokens

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and

IAuction(staderConfig.getAuctionContract()).createLot(sdSlashed);
emit SDSLashedFromUtilize(_operator, sdSlashFromUtilized);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get casing right please.

uint256 sdSlashFromUtilized = operatorSelfBondedSD >= sdSlashed ? 0 : sdSlashed - operatorSelfBondedSD;
operatorSDBalance[_operator] -= (sdSlashed - sdSlashFromUtilized);
if (sdSlashFromUtilized > 0) {
operatorUtilizedSDBalance[_operator] -= sdSlashFromUtilized;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this the right place to inform the utility pool of the slashed SD?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think there is any use case of informing the utility pool

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please simplify this logic.

sdToSlashFromSelfBonded = math.min(operatorSelfBondedSD, sdSlashed)
operatorSDBalance[_operator] -= sdToSlashFromSelfBonded

operatorUtilizedSDBalance[operator] -= (sdSlashed - sdToSlashFromSelfBonded)

This avoids the if stmt.

@sanjay-staderlabs sanjay-staderlabs merged commit 8b8223f into mainnet_V0 Apr 1, 2024
0 of 4 checks passed
@sanjay-staderlabs sanjay-staderlabs deleted the feat/SD_Utility_Pool branch April 1, 2024 09:56
jac18281828 pushed a commit that referenced this pull request Apr 18, 2024
* basic utility pool structure

* sdCollateral intergration with utilityPool

* Rename SDx.sol to SDX.sol

* terminology change

* SD Incentive Controller (#210)

* Initial code

* Change terminologies

* IncentiveController->SDIncentiveController

* Run prettier

* Use block number and read from staderConfig

* utilize flow

* dwlwgator withdraw flow

* seperate function in node registry to utilze SD

* view function to get latest data

* Liquidation (#211)

* User struct

* mapping

* calculation

* liquidationCall initial

* Add riskconfig

* Add back comments

* include pause functionality

* repay flow changes and comments

* Operator reward integration (#213)

* init

* Introduce owedAmount

* Update OperatorRewardsCollector.sol

* Add PoolUtils

* claimLiquidation

* Fix compile

* Fix claimFor

* Add liquidator data

* review fixes

* deposit SD reward as collateral changes

* Fix compilation

* Change function orders

* Fix review

* Add exit operator

* deposit SD reward as collateral flow changes

* Fix review

* Use operatorUtilizedSDBalance

* custom error message

* deploy script for utility pool

* Updates on incentiveController

* Add docs and checkers

* fix claim function time cool down logic

* Add withdrawable

* rename function and variables

* Add non-existent liquidation check

* fix sdCollateral withdraw function

* Fix claim logic

* refactor slash SD

* whenNotPaused modifier

* Claim rewards during requestWithdraw

* review fixes

* change in request withdraw logic

* Review fix

* Introduce weth

* introducing withdrawOnBehalf in SDCollateral

* Transfer back utilized SD

* add getter in interface

* incentiveController and addValidatorKey fix

* test case for utilze and delegate flow

* referral Id for adding validator keys

* sdCollateral test cases

* SD token decimal adjust

* Multiply by DECIMAL

* Liquidation test

* Only manager role for certain functions

* test fix

* Fix weth issue

* Small fix and unit test

* Minimum reward amount

* Claim available amount

* Lint test

* Add start incentive later test

* SDP-06 fix

* SDP-11 fix

* Fix SDP-03

* SDP-02 fix

* push back SDP-03 fix

* SDP-07 fix

* SDP-17 fix

* Take initial _delegate into consideration

* whenNotPaused test cases

* comment fix

* Expand liquidation call tests

* Update SDIncentiveController.t.sol

* Separate claim and claimLiquidation

* Add test

* Quick fix

* Remove claimFor

* Fix test

* Lint and add tests

* small change claim

* Add emit tests

* Refactor test

* add emit test

* claim after liquidation

* change initial delegate amount to 1 SD

* Initialise risk config at initialize

* Internal function prefix with _

* renaming change

* Collateral in ETH and expose liquidationIndexByOperator

* rounding up interest in ETH

* reward collector test fixed

* foundry deploy script

* minimum withdraw and delegate limits

* rounding up cTokenShare in requestWithdrawWithSD call

* fix utilityPool with min delegate amount

* add clearUtilizedPosition function

* add totalUtilizedSD getter in interface

* clearing utilized position using withdrawOnBehalf

* optimize _transferBackUtilizedSD

* handling of edge cases when nonTerminalKeys are 0

* update interface

* add utilityPool deploy script

* introduce claimWithAmount function in rewardCollector

* fix: only call withdraw if balance of nodeELVault greater than 0

* updating operatorRewardsCollector Interface

* adding third party license file

* fix formatting of README

* add title in License file

* formatting the title of License file

---------

Co-authored-by: Sanjay Yadav <[email protected]>
Co-authored-by: Dulguun <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants